﻿#region Header
// Copyright 2007-2011, Jerónimo Milea
// 
// This file is part of NetJsWire.
// 
//     NetJsWire is free software: you can redistribute it and/or modify
//     it under the terms of the GNU General Public License as published by
//     the Free Software Foundation, either version 3 of the License, or
//     (at your option) any later version.
// 
//     NetJsWire is distributed in the hope that it will be useful,
//     but WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//     GNU General Public License for more details.
// 
//     You should have received a copy of the GNU General Public License
//     along with NetJsWire.  If not, see <http://www.gnu.org/licenses/>.
#endregion

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.Layout;
using NetJsWire.JsonRpcHandler;
using NetJsWire.JsonRpcHandler.Attributes;
using NetJsWire.JsonRpcHandler.Util;
using NetJsWire.Util;
using NetJsWire.Widgets.Config;
using NetJsWire.Widgets.Core;
using NetJsWire.Widgets.Ui.Layout;
using Panel = System.Windows.Forms.Panel;

namespace NetJsWire.Widgets.Ui.Form
{
    [Renderer( typeof( Renderers.Form.FormPanel ) )]
    public partial class FormPanel : Panel, IWidget, IWidgetContainer
    {
        private readonly IRenderer _renderer;
        private ButtonAlign _buttonAlign = ButtonAlign.Right;
        private bool _collapsible;
        private IConfigOptions _configOptions;
        private LabelAlign _labelAlign = LabelAlign.Left;
        private string _labelSeparator = ":";
        private int _labelWidth = 100;
        private LayoutType _layout = LayoutType.Form;
        private SubmitMethod _submitMethod = SubmitMethod.POST;
        private string _title;
        private string _waitMessage = "Saving data...";
        private bool _waitMsgTarget;
        private string _waitTitle = "Please Wait...";
        private FormLayoutEngine layoutEngine;

        public FormPanel()
        {
            InitializeComponent();

            _renderer = Helper.GetRenderer( this );

            SetStyle( ControlStyles.UserPaint, true );
            SetStyle( ControlStyles.AllPaintingInWmPaint, true );
            SetStyle( ControlStyles.DoubleBuffer, true );
        }

        public FormPanel( IContainer container )
        {
            container.Add( this );

            InitializeComponent();

            _renderer = Helper.GetRenderer( this );

            SetStyle( ControlStyles.UserPaint, true );
            SetStyle( ControlStyles.AllPaintingInWmPaint, true );
            SetStyle( ControlStyles.DoubleBuffer, true );
        }

        internal bool HasForm_Post
        {
            get
            {
                var o = form_post;
                return o != null;
            }
        }

        public string UrlLoad { get; set; }

        public string UrlSubmit { get; set; }

        [DefaultValue( ( string ) null )]
        public string ClientItems { get; set; }

        [DefaultValue( SubmitMethod.POST )]
        public SubmitMethod SubmitMethod
        {
            get { return _submitMethod; }
            set { _submitMethod = value; }
        }

        [DefaultValue( false )]
        public bool FileUpload { get; set; }

        [DefaultValue( false )]
        public bool StandardSubmit { get; set; }

        [DefaultValue( false )]
        public bool Border { get; set; }

        [DefaultValue( ButtonAlign.Right )]
        public ButtonAlign ButtonAlign
        {
            get { return _buttonAlign; }
            set
            {
                //if ( !Renderer.Rendered && value != NetJsWire.ButtonAlign.Right || value != _buttonAlign )
                {
                    Renderer.SetConstructionProperty( "buttonAlign", value.ToString().ToLower() );
                }

                _buttonAlign = value;

                if ( DesignMode )
                {
                    PerformLayout();
                }
            }
        }

        [DefaultValue( LabelAlign.Left )]
        public LabelAlign LabelAlign
        {
            get { return _labelAlign; }
            set { _labelAlign = value; }
        }

        [DefaultValue( ( string ) null )]
        public string Defaults { get; set; }

        [DefaultValue( ( string ) null )]
        public string BodyStyle { get; set; }

        [DefaultValue( false )]
        public bool MonitorValid { get; set; }

        [DefaultValue( false )]
        public bool Frame { get; set; }

        [DefaultValue( 100 )]
        public int LabelWidth
        {
            get { return _labelWidth; }
            set
            {
                _labelWidth = value;
                Invalidate();
            }
        }

        [DefaultValue( "Saving data..." )]
        public string WaitMessage
        {
            get { return _waitMessage; }
            set { _waitMessage = value; }
        }

        [DefaultValue( false )]
        public bool AutoSaveFiles { get; set; }

        [DefaultValue( false )]
        public bool AutoHeight { get; set; }

        [DefaultValue( ( string ) null )]
        public string SaveFilesPath { get; set; }

        [DefaultValue( ":" )]
        public string LabelSeparator
        {
            get { return _labelSeparator; }
            set
            {
                _labelSeparator = value;
                Invalidate();
            }
        }

        [DefaultValue( ( string ) null ), RefreshProperties( RefreshProperties.Repaint )]
        public string Title
        {
            get { return _title; }
            set
            {
                if ( !Renderer.Rendered && !string.IsNullOrEmpty( value ) )
                {
                    Renderer.SetConstructionProperty( "title", value );
                }
                //if ( !string.IsNullOrEmpty( value ) && string.IsNullOrEmpty( _title ) )
                //{
                //    Height += 23;
                //}
                //else if ( string.IsNullOrEmpty( value ) && !string.IsNullOrEmpty( _title ) )
                //{
                //    Height -= 23;
                //}

                _title = value;
                Invalidate();
            }
        }

        public override LayoutEngine LayoutEngine
        {
            get
            {
                if ( layoutEngine == null )
                {
                    layoutEngine = new FormLayoutEngine();
                }

                return layoutEngine;
            }
        }

        [DefaultValue( true )]
        public bool AutoPositionedButtons { get; set; }

        [DefaultValue( false )]
        public bool Collapsible
        {
            get { return _collapsible; }
            set
            {
                if ( value != _collapsible && !Renderer.Rendered )
                {
                    Renderer.SetConstructionProperty( "collapsible", value );
                }
                _collapsible = value;
            }
        }

        [DefaultValue( false )]
        public bool WaitMsgTarget
        {
            get { return _waitMsgTarget; }
            set
            {
                _waitMsgTarget = value;

                if ( !Renderer.Rendered && value )
                {
                    Renderer.SetConstructionProperty( "waitMsgTarget", true );
                }
            }
        }

        [DefaultValue( "Please Wait..." )]
        public string WaitTitle
        {
            get { return _waitTitle; }
            set
            {
                if ( !Renderer.Rendered && !string.IsNullOrEmpty( value ) && "Please Wait..." != value )
                {
                    Renderer.SetConstructionProperty( "waitTitle", true );
                }

                _waitTitle = value;
            }
        }

        #region IWidget Members

        public IRenderer Renderer
        {
            get { return _renderer; }
        }

        public void On( string name, string function )
        {
            throw new NotImplementedException();
        }

        public void AddClass( string cls )
        {
            throw new NotImplementedException();
        }

        public void RemoveClass( string cls )
        {
            throw new NotImplementedException();
        }

        [DefaultValue( false )]
        [Description(
           "If the framework should generate a global Javascript variable that points to the Widget, the name of the variable will be the same as ClientID property of the Renderer."
           )]
        public bool GenerateClientMember { get; set; }

        [RefreshProperties( RefreshProperties.All ),
         DesignerSerializationVisibility( DesignerSerializationVisibility.Content ), Category( "Config" )]
        public IConfigOptions ConfigOptions
        {
            get
            {
                if ( _configOptions == null )
                {
                    _configOptions = new FormPanelConfigOptions( this ) { Xtype = "form" };
                }
                return _configOptions;
            }
        }

        #endregion

        #region IWidgetContainer Members

        [DefaultValue( LayoutType.Form ),
         RefreshProperties( RefreshProperties.Repaint )]
        public LayoutType Layout
        {
            get { return _layout; }
            set { _layout = value; }
        }

        [Category( "LayoutConfig" )]
        public string LayoutConfig { get; set; }

        #endregion

        internal event EventHandler<FormPostedEventArgs> form_post;
        public event EventHandler<FormPostedEventArgs> FormPosted;

        internal void RaiseFormPosted( FormPostedEventArgs e )
        {
            var o = FormPosted;

            if ( null != o )
            {
                FormPosted( this, e );
            }
        }

        protected override void OnPaint( PaintEventArgs e )
        {
            base.OnPaint( e );

            foreach ( Control ctrl in Controls )
            {
                if ( ctrl is IFormField )
                {
                    if ( !string.IsNullOrEmpty( ( ctrl as IFormField ).FieldLabel ) )
                    {
                        var loc = ctrl.Location;
                        switch ( LabelAlign )
                        {
                            case LabelAlign.Left:
                                loc.Offset( -( LabelWidth + 5 ), 0 );
                                break;
                            case LabelAlign.Top:
                                loc.Offset( 0, -18 );
                                break;
                            case LabelAlign.Right:
                                break;
                            default:
                                break;
                        }

                        e.Graphics.DrawString(
                            ( ctrl as IFormField ).FieldLabel +
                            ( !string.IsNullOrEmpty( LabelSeparator ) ? LabelSeparator : "" ), Font,
                            Brushes.Black, loc );
                    }
                }
            }
        }
    }
}